package com.api.rc.controller;

import com.api.core.annotation.PowerEnable;
import com.api.core.config.AuthUser;
import com.api.core.controller.Ctrl;
import com.api.core.response.Result;
import com.api.core.response.ResultCode;
import com.api.core.response.ResultGenerator;
import com.api.rc.enums.RoomFee;
import com.api.rc.enums.RoomStatus;
import com.api.rc.form.HostQuestionForm;
import com.api.rc.form.HostTestForm;
import com.api.rc.service.HostService;
import com.api.rc.service.RapidChallengeService;
import com.api.rc.vo.HostLevelRuleVo;
import com.api.rc.vo.HostOverviewVo;
import com.api.rc.vo.HostVo;
import com.api.rc.vo.RoomVo;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.ImmutableMap;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.*;
import org.springframework.security.core.Authentication;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author RenQiang
 * @date 2021/7/5
 */
@Slf4j
@RestController
@RequestMapping(value = "/rapid-challenge/host")
@PowerEnable(name = "主持人", url = "/rapid-challenge/host")
@Api(value = "主持人", tags = {HostController.API_TAG})
@Validated
public class HostController extends Ctrl {
    public static final String API_TAG = "主持人";

    private final HostService hostService;
    private final RapidChallengeService rapidChallengeService;

    public HostController(HostService hostService, RapidChallengeService rapidChallengeService) {
        this.hostService = hostService;
        this.rapidChallengeService = rapidChallengeService;
    }

    @ApiOperation(value = "设置主持人问题", tags = {API_TAG}, notes = "设置主持人问题")
    @PostMapping("/batch-update-questions")
    public Result batchUpdateQuestions(@Valid @NotEmpty @RequestBody List<HostQuestionForm> hostQuestionForms) {
        try {
            hostService.batchUpdateQuestions(hostQuestionForms);
        } catch (IllegalArgumentException e) {
            log.error("保存主持人问题失败", e);
            return ResultGenerator.genFailResult(ResultCode.FAIL.code(), e.getMessage());
        }
        return ResultGenerator.genSuccessResult();
    }

    @ApiOperation(value = "获取主持人问题列表", tags = {API_TAG}, notes = "获取主持人问题列表")
    @GetMapping("/list-questions")
    public Result listQuestions() {
        List<HostQuestionForm> hostQuestions = hostService.getQuestions();
        return ResultGenerator.genSuccessResult(hostQuestions);
    }

    @ApiOperation(value = "获取主持人问题", tags = {API_TAG}, notes = "获取主持人问题")
    @GetMapping("/get-questions")
    public Result getQuestions() {
        List<HostQuestionForm> hostQuestions = hostService.getQuestions();
        hostQuestions.forEach(q -> q.getAnswers().forEach(a -> a.setIsRight(null)));
        return ResultGenerator.genSuccessResult(hostQuestions);
    }

    @ApiOperation(value = "修改主持人教程视频", tags = {API_TAG}, notes = "修改主持人教程视频")
    @PostMapping("/update-tutorial-video")
    public Result updateTutorialVideo(@ApiParam("视频URL") @NotBlank @RequestParam String videoUrl) {
        try {
            hostService.updateTutorialVideo(videoUrl);
        } catch (IllegalArgumentException e) {
            log.error("保存主持人教程视频失败", e);
            return ResultGenerator.genFailResult(ResultCode.FAIL.code(), e.getMessage());
        }
        return ResultGenerator.genSuccessResult();
    }

    @ApiOperation(value = "获取主持人教程视频", tags = {API_TAG}, notes = "获取主持人教程视频")
    @GetMapping("/get-tutorial-video")
    public Result getTutorialVideo() {
        String tutorialVideo = hostService.getTutorialVideo();
        return ResultGenerator.genSuccessResult(tutorialVideo);
    }

    @ApiOperation(value = "主持人答题", tags = {API_TAG}, notes = "主持人答题")
    @PostMapping("/test")
    public Result test(Authentication authentication,
                       @Valid @NotEmpty @RequestBody List<HostTestForm> hostTestForms) {
        try {
            AuthUser authUser = getAuthUser(authentication);
            HostOverviewVo hostOverviewVo = hostService.test(authUser.getId(), hostTestForms);
            return ResultGenerator.genSuccessResult(hostOverviewVo);
        } catch (IllegalArgumentException e) {
            log.error("保存主持人答题结果失败", e);
            return ResultGenerator.genFailResult(ResultCode.FAIL.code(), e.getMessage());
        }
    }

    @ApiOperation(value = "获取主持人等级规则", tags = {API_TAG}, notes = "获取主持人等级规则")
    @GetMapping("/get-level-rules")
    public Result getLevelRules() {
        List<HostLevelRuleVo> hostLevelRuleVos = hostService.getLevelRules();
        return ResultGenerator.genSuccessResult(hostLevelRuleVos);
    }

    @ApiOperation(value = "获取主持人概况", tags = {API_TAG}, notes = "获取主持人概况")
    @GetMapping("/get-overview")
    public Result getOverview(Authentication authentication) {
        try {
            AuthUser authUser = getAuthUser(authentication);
            HostOverviewVo hostOverviewVo = hostService.getOverview(authUser.getId());
            return ResultGenerator.genSuccessResult(hostOverviewVo);
        } catch (IllegalArgumentException e) {
            log.error("获取主持人概况失败", e);
            return ResultGenerator.genFailResult(ResultCode.FAIL.code(), e.getMessage());
        }
    }

    @ApiOperation(value = "获取主持人可用的房费列表", tags = {API_TAG}, notes = "获取主持人可用的房费列表")
    @GetMapping("/get-available-room-fees")
    public Result getAvailableRoomFees(Authentication authentication) {
        try {
            AuthUser authUser = getAuthUser(authentication);
            List<RoomFee> availableRoomFees = hostService.getAvailableRoomFees(authUser.getId());
            List<Map<String, Object>> mapList = availableRoomFees.stream()
                    .map(f -> ImmutableMap.<String, Object>of("key", f.name(), "fee", f.getFee()))
                    .collect(Collectors.toList());
            return ResultGenerator.genSuccessResult(mapList);
        } catch (IllegalArgumentException e) {
            log.error("获取主持人可用的房费列表失败", e);
            return ResultGenerator.genFailResult(ResultCode.FAIL.code(), e.getMessage());
        }
    }

    @ApiOperation(value = "分页查询主持过的比赛", tags = {API_TAG}, notes = "分页查询主持过的比赛")
    @GetMapping("/list-challenge-by-page")
    public Result listChallengeByPage(Authentication authentication,
                                      @ApiParam(value = "游戏ID") @RequestParam(required = false) Long gameId,
                                      @ApiParam(value = "房间状态") @RequestParam(required = false) RoomStatus roomStatus,
                                      @ApiParam(value = "页号") @RequestParam(defaultValue = "1") Integer page,
                                      @ApiParam(value = "分页大小") @RequestParam(defaultValue = "10") Integer size) {
        AuthUser authUser = getAuthUser(authentication);
        Map<String, Object> queryParams = new HashMap<>(8);
        if (gameId != null) {
            queryParams.put("gameId", gameId);
        }
        if (roomStatus != null) {
            queryParams.put("roomStatus", roomStatus);
        }
        queryParams.put("hostUserId", authUser.getId());
        PageInfo<RoomVo> pageInfo = rapidChallengeService.listByPage(queryParams, page, size);
        pageInfo.getList()
                .forEach(roomVo -> {
                    roomVo.setPlatformRewardCoins(null);
                    roomVo.setHostEarnCoins(null);
                });
        return ResultGenerator.genSuccessResult(pageInfo);
    }

    @ApiOperation(value = "分页查询主持人", tags = {API_TAG}, notes = "分页查询主持人")
    @GetMapping("/list-host-by-page")
    public Result listHostByPage(@ApiParam(value = "主持人名称") @RequestParam(required = false) String hostName,
                                 @ApiParam(value = "游戏ID") @RequestParam(required = false) Long gameId,
                                 @ApiParam(value = "页号") @RequestParam(defaultValue = "1") Integer page,
                                 @ApiParam(value = "分页大小") @RequestParam(defaultValue = "10") Integer size) {
        Map<String, Object> queryParams = new HashMap<>(4);
        if (StringUtils.isNotEmpty(hostName)) {
            queryParams.put("hostName", hostName);
        }
        if (gameId != null) {
            queryParams.put("gameId", gameId);
        }
        PageInfo<HostVo> pageInfo = hostService.listByPage(queryParams, page, size);
        return ResultGenerator.genSuccessResult(pageInfo);
    }

    @ApiOperation(value = "导出", tags = {API_TAG}, notes = "导出")
    @GetMapping("/export")
    public void export(@ApiParam(value = "主持人名称") @RequestParam(required = false) String hostName,
                         @ApiParam(value = "游戏ID") @RequestParam(required = false) Long gameId, HttpServletResponse response) throws IOException {
        Map<String, Object> queryParams = new HashMap<>(4);
        if (StringUtils.isNotEmpty(hostName)) {
            queryParams.put("hostName", hostName);
        }
        if (gameId != null) {
            queryParams.put("gameId", gameId);
        }
        PageInfo<HostVo> pageInfo = hostService.listByPage(queryParams, 1, 0);

        HSSFWorkbook workbook = new HSSFWorkbook();
        HSSFSheet sheet = workbook.createSheet("用户信息");
        // 设置要导出的文件的名字
        String fileName = "mmc_users"  + new Date() + ".xls";
        // 新增数据行，并且设置单元格数据
        int rowNum = 1;

        String[] headers = { "ID","User Name", "Email Address", "Phone Number", "Rapid Challenge","Host Assessment","Coins'earned"};
        HSSFRow row = sheet.createRow(0);
        for(int i=0;i<headers.length;i++){
            HSSFCell cell = row.createCell(i);
            HSSFRichTextString text = new HSSFRichTextString(headers[i]);
            cell.setCellValue(text);
        }
        //在表中存放查询到的数据放入对应的列
        for (HostVo item : pageInfo.getList()) {
            HSSFRow row1 = sheet.createRow(rowNum);
            row1.createCell(0).setCellValue(item.getUserInfo().getId());
            row1.createCell(1).setCellValue(item.getUserInfo().getFullName());
            row1.createCell(2).setCellValue(item.getUserInfo().getEmail());
            row1.createCell(3).setCellValue(item.getEarningCoins().toString());
            row1.createCell(4).setCellValue(item.getEarningCoins().toString());
            row1.createCell(5).setCellValue(item.getTestScore()/item.getTestTotalScore());
            rowNum++;
        }

        response.setContentType("application/octet-stream");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName);
        response.flushBuffer();
        workbook.write(response.getOutputStream());
    }

    @ApiOperation(value = "禁用或启用主持人", tags = {API_TAG}, notes = "禁用或启用主持人")
    @PostMapping("/block-host")
    public Result blockHost(@ApiParam("主持人ID") @RequestParam Long hostId,
                            @ApiParam("是否可用") @RequestParam Boolean available) {
        try {
            hostService.updateHostAvailable(hostId, available);
            return ResultGenerator.genSuccessResult();
        } catch (IllegalArgumentException e) {
            log.error("禁用或启用主持人失败", e);
            return ResultGenerator.genFailResult(ResultCode.FAIL.code(), e.getMessage());
        }
    }
}
